package com.xuexuehai.BQMS.util;

import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.format.DateTimeParseException;
import java.util.Scanner;

/**
 * BQMS系统的工具类，用于判断输入等
 *
 * @Author: xuexuehai
 * @MailBox: xuehai.xue@qq.com
 * @Date: 2021/5/8 9:50 下午
 */
public class BQMSUtility {
    private static Scanner scanner = new Scanner(System.in);

    /**
     * 从键盘读取一个长度不超过10000000位的字符串如果解析成float失败则重复输入，并将其作为方法的返回值
     */
    public static float readFloat() {
        float n;
        for (; ; ) {
            String str = readKeyBoard(10000000, false);
            try {
                n = Float.parseFloat(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误，请重新输入：");
            }
        }
        return n;
    }

    /**
     * 判断是否是日期格式
     */
    public static LocalDate readDate() {
        String date;
        LocalDate localDate;
        for (; ; ) {
            date = readKeyBoard(10, false);
            try {
                if (date.matches("((((19|20)\\d{2})-(0?(1|[3-9])|1[012])-(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2})-(0?[13578]|1[02])-31)|(((19|20)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))-0?2-29))$")) {
                    localDate = LocalDate.parse(date);
                    break;
                }else {
                    System.out.println("输入不合法，正确的日期格式是(yyyy-MM-dd).");
                }
            } catch(DateTimeException e){
                System.out.println("输入不合法，正确的日期格式是(yyyy-MM-dd).");
            }
        }
        return localDate;
    }

    /**
     * 从键盘获取输入流
     */
    private static String readKeyBoard(int limit, boolean blankReturn) {
        String line = "";

        while (scanner.hasNextLine()) {
            line = scanner.nextLine();
            if (line.length() == 0) {
                if (blankReturn) {
                    return line;
                } else {
                    continue;
                }
            }

            if (line.length() < 1 || line.length() > limit) {
                System.out.print("输入长度（不大于" + limit + "）错误，请重新输入：");
                continue;
            }
            break;
        }

        return line;
    }

    /**
     * 用于界面菜单的选择。该方法读取键盘，如果用户输入‘1’~‘5’中的任意字符
     * 则方法返回，返回值为用户输入值
     */
    public static char readMenuSelection(int type) {
        char c = ' ';
        if (type == 0) {
            for (; ; ) {
                String str = readKeyBoard(1, false);
                c = str.charAt(0);
                if (c != '1' && c != '2' && c != '3' && c != '4' && c != '5' && c != '6' && c != '7') {
                    System.out.print("选择错误，请重新输入");
                } else {
                    break;
                }
            }
        }
        if (type == 1) {
            for (; ; ) {
                String str = readKeyBoard(1, false);
                c = str.charAt(0);
                if (c != '1' && c != '2' && c != '3') {
                    System.out.print("选择错误，请重新输入");
                } else {
                    break;
                }
            }
        }
        return c;
    }

    /**
     * 从键盘读取一个字符，并将其作为方法的返回值
     */
    public static char readChar() {
        String str = readKeyBoard(1, false);
        return str.charAt(0);
    }

    /**
     * 从键盘读取一个字符，并将其作为方法的返回值
     * 如果用户不输入字符而直接回车，方法将以defaultValue作为返回值
     */
    public static char readChar(char defaultValue) {
        String str = readKeyBoard(1, true);
        return (str.length() == 0) ? defaultValue : str.charAt(0);
    }

    /**
     * 从键盘读取一个长度不超过2位的整数，并将其作为方法的返回值
     */
    public static int readInt() {
        int n;
        for (; ; ) {
            String str = readKeyBoard(2, false);
            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误，请重新输入：");
            }
        }
        return n;
    }

    /**
     * 从键盘读取一个长度不超过10000位的整数，并将其作为方法的返回值
     */
    public static int readIntBig() {
        int n;
        for (; ; ) {
            String str = readKeyBoard(10000, false);
            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误，请重新输入：");
            }
        }
        return n;
    }

    /**
     * 从键盘读取一个长度不超过2位的整数，并将其作为方法的返回值
     * 如果用户不输入字符而直接回车，方法将以defaultValue作为返回值
     */
    public static int readInt(int defaultValue) {
        int n;
        for (; ; ) {
            String str = readKeyBoard(2, true);
            if ("".equals(str)) {
                return defaultValue;
            }

            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("输入数字有误，请重新输入");
            }
        }
        return n;
    }

    /**
     * 从键盘读取一个长度不超过limit的字符串，并将其作为返回值
     */
    public static String readString(int limit) {
        return readKeyBoard(limit, false);
    }

    /**
     * 从键盘读取一个长度不超过limit的字符串，并将其作为返回值
     * 如果用户不输入字符而直接回车，方法将以defaultValue作为返回值
     */
    public static String readString(int limit, String defaultValue) {
        String str = readKeyBoard(limit, true);
        return "".equals(str) ? defaultValue : str;
    }

    /**
     * 用于确认选择的输入。该方法从键盘读取‘Y’或‘N’。并将其作为方法的返回值
     */
    public static char readConfirmSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false).toUpperCase();
            c = str.charAt(0);
            if (c == 'Y' || c == 'N') {
                break;
            } else {
                System.out.print("输入有误，请重新输入：");
            }
        }
        return c;
    }
}
